package com.zhang.zxx.boot.common.base;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.zhang.zxx.boot.common.core.SpringContextHolder;
import com.zhang.zxx.boot.common.enums.MsgEunm;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Arrays;

/**
 * Response:REST响应体
 *
 * @author zhangxiaoxiang
 * @date 2021年12月11日
 */
@Data
@Accessors(chain = true)
@ApiModel("Response REST响应体")
public class Response<DATA> implements Serializable {

    private static final long serialVersionUID = -1L;

    @ApiModelProperty(value = "请求状态[必返回]",example = "成功")
    private String status;

    @JsonInclude(value = JsonInclude.Include.NON_NULL)
    @ApiModelProperty("信息[如果有,没有则不返回]")
    private String message;

    @ApiModelProperty(value = "消息说明数字码[必返回]",example = "00000")
    private String statusCode;

    @ApiModelProperty("返回数据[必返回]")
    private DATA data;

    @JsonInclude(value = JsonInclude.Include.NON_NULL)
    @ApiModelProperty(value = "自定义附加响应数据体[如果有,没有则不返回]")
    private Object customData;

    @JsonInclude(value = JsonInclude.Include.NON_EMPTY)
    @ApiModelProperty(value = "异常堆栈信息[仅在dev环境返回,主要给后端查看]")
    private StackTraceElement[] errorStackTrace;

    @JsonInclude(value = JsonInclude.Include.NON_NULL)
    @ApiModelProperty("总条数[如果有,没有则不返回]")
    private Integer total;

    public static <D> Response<D> success() {
        Response<D> response = new Response<>();
        response.status = MsgEunm.SUCCESS.getMessage();
        response.message = MsgEunm.SUCCESS.getMessage();
        response.statusCode = MsgEunm.SUCCESS.getCode();
        return response;
    }

    public static <D> Response<D> success(MsgEunm emsg) {
        Response<D> success = Response.<D>success();
        if (emsg != null) {
            success.message = emsg.getMessage();
            success.statusCode = emsg.getCode();
        }
        return success;
    }

    public static <D> Response<D> data(D data) {
        Response<D> success = Response.<D>success();
        success.setData(data);
        return success;
    }

    public static <D> Response<D> failed() {
        Response<D> response = new Response<>();
        response.status = MsgEunm.FAILED.getMessage();
        response.message = MsgEunm.FAILED.getMessage();
        response.statusCode = MsgEunm.FAILED.getCode();
        return response;
    }

    public static <D> Response<D> failed(MsgEunm emsg) {
        Response<D> failed = Response.<D>failed();
        if (emsg != null) {
            failed.message = emsg.getMessage();
            failed.statusCode = emsg.getCode();
        }
        return failed;
    }

    public Response<DATA> setCount(Integer count) {
        return this.setTotal(count);
    }


    public void setErrorStackTrace(StackTraceElement[] errorStackTrace) {
        if (SpringContextHolder.isDebug()) {
            int stackHeight = Math.min(errorStackTrace.length, 10);
            this.errorStackTrace = Arrays.copyOf(errorStackTrace, stackHeight);
        }
    }
}
